package ru.surfstudio.graduate.activity;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import ru.surfstudio.graduate.R;
import ru.surfstudio.graduate.bean.ChannelManager;
import ru.surfstudio.graduate.data.Channel;
import ru.surfstudio.graduate.data.Feed;
import ru.surfstudio.graduate.handler.FeedsAddHandler;
import ru.surfstudio.graduate.service.HttpService;
import ru.surfstudio.graduate.task.FeedSearchTask;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Messenger;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class FeedListActivity extends AbstractRssActivity {
	
	public static final String MARK_FEED_LIST = "FEED_LIST";
	public static final String MARK_CHANNEL = "CHANNEL";
	
	private static final String TAG = "FeedListActivity";
	
	private ListView feedListView;
	
	private Channel channel;
	public List<Feed> feedList;
	
	private FeedListAdapter adapter;
	
	private FeedListActivityState state;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main_activity);
		
		Log.d(TAG, ">>> START ACTIVITY");
		state = (FeedListActivityState) getLastNonConfigurationInstance();
		if (state == null) {
			Log.d(TAG, ">>> create state");
			state = new FeedListActivityState(this);
		} else {
			state.attach(this);
		}
		
		channel = (Channel) getIntent().getSerializableExtra(MARK_CHANNEL);
		feedList = new ArrayList<Feed>();
		adapter = new FeedListAdapter(feedList);
		
		setTitle(channel.getName());
		
		feedListView = (ListView) findViewById(R.id.main_channels_list);
		feedListView.setAdapter(adapter);
		feedListView.setOnItemClickListener(onListClick);
		
	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		
		state.detach();
	}
	
	@Override
	public void onStart() {
		super.onStart();
		
		executeLoadFeedsTask(state.onlyNew);
	}
	
	@Override
    public Object onRetainNonConfigurationInstance() {
		Log.d(TAG, ">>> save state");
        state.detach();
        return state;
    }
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		new MenuInflater(this).inflate(R.menu.feed_list_option, menu);
		return super.onCreateOptionsMenu(menu);
	}
	
	@Override
    public boolean onPrepareOptionsMenu(Menu menu) {
    	menu.findItem(R.id.feed_list_all_menu_item).setVisible(state.onlyNew);
    	menu.findItem(R.id.feed_list_new_menu_item).setVisible(!state.onlyNew);
    	
    	return super.onPrepareOptionsMenu(menu);
    }
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		
		switch (item.getItemId()) {
			case R.id.feed_list_update_menu_item:
				Intent intent = new Intent(FeedListActivity.this, HttpService.class);
				intent.putExtra(HttpService.MARK_HANDLER, new Messenger(state.handler));
				intent.putExtra(HttpService.MARK_TASK, new FeedSearchTask(channel));
				startService(intent);
				return true;
				
			case R.id.feed_list_search_menu_item:
				// TODO Auto-generated method stub
				return true;
			
			case R.id.feed_list_all_menu_item:
				state.onlyNew = false;
				executeLoadFeedsTask(state.onlyNew);
				return true;
				
			case R.id.feed_list_new_menu_item:
				state.onlyNew = true;
				executeLoadFeedsTask(state.onlyNew);
				return true;
		}
		
		return onOptionsItemSelected(item);
	}
	
	@Override
	public void onPostFeedsUpdate(Channel channel) {
		executeLoadFeedsTask(state.onlyNew);
	}
	
	private void executeLoadFeedsTask(boolean onlyNew) {
		if (state.loadFeedsTask == null || state.loadFeedsTask.isCancelled() ||
				state.loadFeedsTask.getStatus().equals(AsyncTask.Status.FINISHED)) {
			
			state.loadFeedsTask = new LoadFeedsTask(this);
			state.loadFeedsTask.execute(onlyNew);
		}
	}
	
	
	private AdapterView.OnItemClickListener onListClick = new AdapterView.OnItemClickListener() {

		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
			
			ArrayList<Integer> feedIdList = new ArrayList<Integer>();
			for (Feed feed : feedList) {
				feedIdList.add(feed.getId());
			}
			
			Intent intent = new Intent(FeedListActivity.this, FeedViewActivity.class);
			intent.putExtra(FeedViewActivity.FEED, adapter.getItem(position));
			intent.putExtra(FeedViewActivity.FEEDS_ID_LIST, feedIdList);
			startActivity(intent);
		}
		
	};
	
	private class FeedListAdapter extends ArrayAdapter<Feed> {
		
		public FeedListAdapter(List<Feed> feedList) {
			super(FeedListActivity.this, R.layout.feed_list_item, feedList);
		}
		
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View row = convertView;
			if (row == null) {
				row = getLayoutInflater().inflate(R.layout.feed_list_item, null);
			}
			
			ViewHolder holder = (ViewHolder) row.getTag();
			if (holder == null) {
				holder = new ViewHolder(row);
				row.setTag(holder);
			}
			
			Feed feed = getItem(position);
			
			holder.nameView.setText(getItem(position).getName());
			if (feed.getFavorites())
				holder.imageView.setImageDrawable(getResources().getDrawable(R.drawable.star));
			else
				holder.imageView.setImageDrawable(getResources().getDrawable(R.drawable.star_white));
			
			return row;
		}
		
		private class ViewHolder {
			
			ImageView imageView;
			TextView nameView;
			  
			ViewHolder(View row) {
				imageView = (ImageView) row.findViewById(R.id.feed_list_favorite_image);
				nameView = (TextView) row.findViewById(R.id.feed_list_name_text);
			}
		}
		
	}
	
	private class LoadFeedsTask extends AsyncTask<Boolean, Void, List<Feed>> {

		private FeedListActivity activity;
		
		public LoadFeedsTask(FeedListActivity activity) {
			attach(activity);
		}
		
		@Override
		protected List<Feed> doInBackground(Boolean... params) {
			Log.d(TAG, ">>> LoadFeedsTask  doInBackground()  start");
			try {
				boolean onlyNew = params[0];
				if (activity != null) {
					return findFeeds(activity.channel, onlyNew);
				}
				
			} catch (SQLException e) {
				Log.e(TAG, e.getMessage(), e);
			} catch (Exception e) {
				Log.e(TAG, e.getMessage(), e);
			}
			return null;
		}
		
		@Override
		protected void onPostExecute(List<Feed> feedList) {
			if (activity != null) {
				if (feedList != null) {
					activity.feedList.clear();
					activity.feedList.addAll(feedList);
					activity.adapter.notifyDataSetChanged();
				}
				else {
					Toast.makeText(activity, R.string.database_error, Toast.LENGTH_LONG)
						.show();
					Log.w(TAG, getString(R.string.database_error));
				}
			}
		}
		
		private List<Feed> findFeeds(Channel channel, boolean onlyNew) throws SQLException {
			ChannelManager channelManager = new ChannelManager(activity.getHelper());
			List<Feed> feedList = null;
			
			switch (channel.getMark()) {
				case ALL:
					if (onlyNew)
						feedList = channelManager.getAllNewFeeds();
					else
						feedList = channelManager.getAllFeeds();
					break;
				case FAVORITE:
					if (onlyNew)
						feedList = channelManager.getNewFavoriteFeeds();
					else
						feedList = channelManager.getAllFavoriteFeeds();
					break;
				case NONE:
					if (onlyNew)
						feedList = channelManager.getNewFeedsByChannel(channel.getId());
					else
						feedList = channelManager.getAllFeedsByChannel(channel.getId());
					break;
			}
			return feedList;
		}
		
		public void detach() {
			activity = null;
		}
		
		public void attach(FeedListActivity activity) {
			this.activity = activity;
		}

	}
	
    /** Activity state */
    private static class FeedListActivityState {

        public LoadFeedsTask loadFeedsTask;
        
        public FeedsAddHandler handler;
        
        public boolean onlyNew = false;
        
        public FeedListActivityState(FeedListActivity activity) {
        	handler = new FeedsAddHandler(activity);
        }
        
        public void attach(FeedListActivity activity) {
        	if (loadFeedsTask != null)
        		loadFeedsTask.attach(activity);
        	
        	handler.attach(activity);
        }
        
        public void detach() {
        	if (loadFeedsTask != null)
        		loadFeedsTask.detach();
        	
        	handler.detach();
        }
        
    }

}
